﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XiAnAirport.Models;
using static XiAnAirport.Models.MqttDataInfo;

namespace XiAnAirport.BUS.Mqtt
{
    public class FXMqttClient
    {
        IMqttClient _mqttClient;
        MqttClientOptions _options;
        string version = string.Empty;
        public static string Master;
        public static bool ClientConnect = false;

        public FXMqttClient()
        {
            try
            {
                version = AppSettingsHelper.Configuration["MqttServer:Version"];
                Init();
            }
            catch (Exception ex)
            {
                LogHelper.MqttLog("Mqtt:" + ex.ToString());
            }
        }


        public IMqttClient MqttClient { get { return _mqttClient; } }

        private void Init()
        {
            try
            {
                _mqttClient = new MqttFactory().CreateMqttClient();

                _mqttClient.UseApplicationMessageReceivedHandler(async c =>
                {
                    try
                    {
                        string topic = c.ApplicationMessage.Topic;
                        string payload = Encoding.UTF8.GetString(c.ApplicationMessage.Payload ?? new byte[] { });
                        //LogHelper.MqttLog(payload);
                        if (topic == version + "/KoneDeviceStateSync")
                        {
                            KoneDeviceStateSync koneDeviceStateSync = JsonConvert.DeserializeObject<KoneDeviceStateSync>(payload);
                            if (koneDeviceStateSync != null)
                            {
                                if (koneDeviceStateSync.Elevator_control_status == 99)
                                {
                                    LogHelper.MqttLog(payload);
                                }
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                elevatorStateBUS.MqttKoneDeviceSync(koneDeviceStateSync);
                            }
                        }
                       
                        else if (topic == version + "/KoneDeviceTemperature")
                        {
                            KoneDeviceTemperature koneDeviceTemperature = JsonConvert.DeserializeObject<KoneDeviceTemperature>(payload);
                            if (koneDeviceTemperature != null)
                            {
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                elevatorStateBUS.KoneDeviceTemperature(koneDeviceTemperature);
                            }
                        }
                        else if (topic == version + "/DeviceStatusTotal/01")
                        {

                            DeviceStatusTotal deviceStatusTotal = JsonConvert.DeserializeObject<DeviceStatusTotal>(payload);
                            if (deviceStatusTotal != null)
                            {
                                MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                mqttDataBUS.MqttDataProcess(deviceStatusTotal, "DeviceStatusTotal", "01");
                            }
                        }
                        else if (topic == version + "/DeviceStatusTotal/02")
                        {
                            DeviceStatusTotal deviceStatusTotal = JsonConvert.DeserializeObject<DeviceStatusTotal>(payload);
                            if (deviceStatusTotal != null)
                            {
                                MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                mqttDataBUS.MqttDataProcess(deviceStatusTotal, "DeviceStatusTotal", "02");
                            }
                        }
                        else if (topic == version + "/DeviceStatusTotal/03")
                        {
                            DeviceStatusTotal deviceStatusTotal = JsonConvert.DeserializeObject<DeviceStatusTotal>(payload);
                            if (deviceStatusTotal != null)
                            {
                                MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                mqttDataBUS.MqttDataProcess(deviceStatusTotal, "DeviceStatusTotal", "03");
                            }
                        }
                        else if (topic == version + "/TodayProcess/01")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayProcess todayProcess = JsonConvert.DeserializeObject<TodayProcess>(payload);
                            if (todayProcess != null)
                            {
                                mqttDataBUS.MqttDataProcess(todayProcess, "TodayProcess", "01");
                            }
                        }
                        else if (topic == version + "/TodayProcess/02")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayProcess todayProcess = JsonConvert.DeserializeObject<TodayProcess>(payload);
                            if (todayProcess != null)
                            {
                                mqttDataBUS.MqttDataProcess(todayProcess, "TodayProcess", "02");
                            }
                        }
                        else if (topic == version + "/TodayProcess/03")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayProcess todayProcess = JsonConvert.DeserializeObject<TodayProcess>(payload);
                            if (todayProcess != null)
                            {
                                mqttDataBUS.MqttDataProcess(todayProcess, "TodayProcess", "03");
                            }
                        }
                        else if (topic == version + "/TodayRuntime/01")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayRuntime todayRuntime = JsonConvert.DeserializeObject<TodayRuntime>(payload);
                            if (todayRuntime != null)
                            {
                                mqttDataBUS.MqttDataProcess("01", "Schindler", "TodayRuntime", todayRuntime.runtime);
                            }
                        }
                        else if (topic == version + "/TodayRuntime/02")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayRuntime todayRuntime = JsonConvert.DeserializeObject<TodayRuntime>(payload);
                            if (todayRuntime != null)
                            {
                                mqttDataBUS.MqttDataProcess("02", "TKE", "TodayRuntime", todayRuntime.runtime);
                            }
                        }
                        else if (topic == version + "/TodayRuntime/03")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            TodayRuntime todayRuntime = JsonConvert.DeserializeObject<TodayRuntime>(payload);
                            if (todayRuntime != null)
                            {
                                mqttDataBUS.MqttDataProcess("03", "TOSHIBA", "TodayRuntime", todayRuntime.runtime);
                            }
                        }
                        else if (topic == version + "/FaultStatistics/01")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultStatistics faultStatistics = JsonConvert.DeserializeObject<FaultStatistics>(payload);
                            if (faultStatistics != null)
                            {
                                mqttDataBUS.MqttFaultStatistics("01", "FaultStatistics", faultStatistics.faultTotal, faultStatistics.faultToday);
                            }
                        }
                        else if (topic == version + "/FaultStatistics/02")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultStatistics faultStatistics = JsonConvert.DeserializeObject<FaultStatistics>(payload);
                            if (faultStatistics != null)
                            {
                                mqttDataBUS.MqttFaultStatistics("02", "FaultStatistics", faultStatistics.faultTotal, faultStatistics.faultToday);
                            }
                        }
                        else if (topic == version + "/FaultStatistics/03")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultStatistics faultStatistics = JsonConvert.DeserializeObject<FaultStatistics>(payload);
                            if (faultStatistics != null)
                            {
                                mqttDataBUS.MqttFaultStatistics("03", "FaultStatistics", faultStatistics.faultTotal, faultStatistics.faultToday);
                            }
                        }
                        else if (topic == version + "/FaultRecordReport/01")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultRecordReport faultRecordReport = JsonConvert.DeserializeObject<FaultRecordReport>(payload);
                            if (faultRecordReport != null)
                            {
                                faultRecordReport.manufacturer = "Schindler";
                                mqttDataBUS.MqttFaultRecordDataProcess(faultRecordReport);
                            }
                        }
                        else if (topic == version + "/FaultRecordReport/02")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultRecordReport faultRecordReport = JsonConvert.DeserializeObject<FaultRecordReport>(payload);
                            if (faultRecordReport != null)
                            {
                                faultRecordReport.manufacturer = "TKE";
                                mqttDataBUS.MqttFaultRecordDataProcess(faultRecordReport);
                            }
                        }
                        else if (topic == version + "/FaultRecordReport/03")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            FaultRecordReport faultRecordReport = JsonConvert.DeserializeObject<FaultRecordReport>(payload);
                            if (faultRecordReport != null)
                            {
                                faultRecordReport.manufacturer = "TOSHIBA";
                                mqttDataBUS.MqttFaultRecordDataProcess(faultRecordReport);
                            }
                        }
                        else if (topic == version + "/KoneDeviceFault")
                        {

                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            KoneFaultReport faultRecordReport = JsonConvert.DeserializeObject<KoneFaultReport>(payload);
                            if (faultRecordReport != null)
                            {
                                //if (FXMqttShareClient.Master == "1" || !FXMqttShareClient.SlaveConnect)
                                //{
                                mqttDataBUS.KoneFaultRecord(faultRecordReport);
                                //}
                                //else
                                //{
                                //    Wait(1000);
                                //    mqttDataBUS.SlaveKoneFaultRecord(faultRecordReport);
                                //}
                            }
                        }
                        else if (topic == version + "/PushKoneDeviceData")
                        {
                            LogHelper.Log("接收到同步的数据：" + payload);
                            List<ShareData> shareData = JsonConvert.DeserializeObject<List<ShareData>>(payload);
                            if (shareData != null)
                            {
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                foreach (var item in shareData)
                                {
                                    if (item.type == "StateSync")
                                    {
                                        List<LiftStateALL> liftStates = JsonConvert.DeserializeObject<List<LiftStateALL>>(item.message.ToString());
                                        elevatorStateBUS.UpdateElevatorState(liftStates);
                                    }
                                    else if (item.type == "RuntimeSync")
                                    {
                                        List<ElevatorStateRunTime> timelist = JsonConvert.DeserializeObject<List<ElevatorStateRunTime>>(item.message.ToString());
                                        elevatorStateBUS.UpdateRunTimeList(timelist);
                                    }
                                    else if (item.type == "RunSync")
                                    {
                                        List<ElevatorStateRun> runlist = JsonConvert.DeserializeObject<List<ElevatorStateRun>>(item.message.ToString());
                                        elevatorStateBUS.UpdateRunList(runlist);
                                    }
                                }
                                elevatorStateBUS.InitDevice();
                                bool result_5 = elevatorStateBUS.PushNoticeMessage("Refresh").Result;
                                bool result_6 = elevatorStateBUS.PushKoneHomeMessage("RefreshHomePage").Result;
                            }
                        }
                        else if (topic == version + "/EscalatorStateSync")
                        {
                            EscalatorSignal escalatorSignal = JsonConvert.DeserializeObject<EscalatorSignal>(payload);
                            if (escalatorSignal != null)
                            {
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                elevatorStateBUS.MqttEscalatorSync(escalatorSignal);
                            }
                        }
                    }
                    catch (Exception e)
                    {

                    }
                });
                _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(e =>
                {
                    StartConnect();
                });
                _options = new MqttClientOptions()
                {
                    //ClientId = CommVars.Configuration.GetSection("MqttServer").GetSection("ClientId").Value
                    ClientId = Guid.NewGuid().ToString() + "Client"
                };
                _options.ChannelOptions = new MqttClientTcpOptions()
                {
                    Server = AppSettingsHelper.Configuration["MqttServer:Server"],
                    Port = int.Parse(AppSettingsHelper.Configuration["MqttServer:Port"]),
                };
                string strName = AppSettingsHelper.Configuration["MqttServer:Username"];
                if (!string.IsNullOrEmpty(strName))
                {
                    _options.Credentials = new MqttClientCredentials()
                    {
                        Username = strName,
                        Password = Encoding.Default.GetBytes(AppSettingsHelper.Configuration["MqttServer:Password"])
                    };
                }
                _options.CleanSession = false;
                _options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
                StartConnect();
            }
            catch (Exception ex)
            {

            }

        }
        public void StartConnect()
        {
            try
            {
                Task t = Task.Factory.StartNew(async () =>
                {
                    while (true)
                    {
                        if (!_mqttClient.IsConnected)
                        {
                            await _mqttClient.ConnectAsync(_options);
                            await _mqttClient.SubscribeAsync(version + "/KoneDeviceFault", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
                            await _mqttClient.SubscribeAsync(version + "/KoneDeviceStateSync", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            //await _mqttClient.SubscribeAsync(version + "/KoneDeviceControl", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            await _mqttClient.SubscribeAsync(version + "/KoneDeviceTemperature", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            await _mqttClient.SubscribeAsync(version + "/PushKoneDeviceData", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            await _mqttClient.SubscribeAsync(version + "/EscalatorStateSync", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                        }
                        else break;
                        Task.Delay(10000).Wait();
                    }
                });
            }
            catch (Exception ex)
            {

            }
        }

        public bool Wait(int milliseconds)
        {
            try
            {
                DateTime startTime = DateTime.Now;
                while (true)
                {
                    TimeSpan secondSpan = new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);
                    if (secondSpan.TotalMilliseconds > milliseconds)
                    {
                        break;
                    }
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
